﻿using System.ComponentModel;
using System.Windows.Input;
using Ninject.Core.Parameters;
using TestBat.IModels.Domain;
using TestBat.IModels.Models;
using TestBat.IViewModels.Base;
using TestBat.IViewModels.Workspaces.Trainees;
using TestBat.ServiceLocator;
using TestBat.ViewModels.Attributes;
using TestBat.ViewModels.Base.Commands;

namespace TestBat.ViewModels.Workspaces.Trainees
{
    public class TraineesViewModel : WorkspaceViewModel, ITraineesViewModel
    {
        public TraineesViewModel(ITraineeGroupModel traineeGroupModel, ITraineeModel traineeModel)
        {
            this.traineeGroupModel = traineeGroupModel;
            this.traineeModel = traineeModel;
        }


        public ITraineeGroupListViewModel TraineeGroupList
        {
            get
            {
                if (traineeGroupList == null)
                {
                    traineeGroupList = DefaultServiceLocator.Get<ITraineeGroupListViewModel>(With.Parameters.ConstructorArgument("checkUnsavedChanges", true));

                    traineeGroupList.PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
                    { // also changed the "Active" property when changing the selection
                        if (e.PropertyName == "Selected")
                            NotifyPropertyChanged(() => this.ActiveTraineeGroup);
                    };
                }

                return traineeGroupList;
            }
        }

        public ITraineeListViewModel TraineeList
        {
            get
            {
                if (traineeList == null)
                {
                    traineeList = DefaultServiceLocator.Get<ITraineeListViewModel>(); // TODO: use factory

                    traineeList.PropertyChanged += (object sender, PropertyChangedEventArgs e) =>
                    { // also changed the "Active" property when changing the selection
                        if (e.PropertyName == "Selected")
                            NotifyPropertyChanged(() => this.ActiveTrainee);
                    };
                }

                return traineeList;
            }
        }

        public ICommand AddTraineeGroupCommand
        {
            get
            {
                return new RelayCommand(e => AddTraineeGroup());
            }
        }

        public ICommand DeleteTraineeGroupCommand
        {
            get
            {
                return new RelayCommand(e => DeleteTraineeGroup(), e => TraineeGroupList.Selected != null);
            }
        }

        public IViewModel ActiveTraineeGroup
        {
            get { if (activeTraineeGroup != null) return activeTraineeGroup; return TraineeGroupList.Selected; }
            private set { activeTraineeGroup = value; NotifyPropertyChanged(() => this.ActiveTraineeGroup); }
        }

        public IViewModel ActiveTrainee
        {
            get
            {
                if (activeTrainee != null)
                    return activeTrainee;
                return TraineeList.Selected;
            }
            private set { activeTrainee = value; NotifyPropertyChanged(() => this.ActiveTrainee); }
        }

        public ICommand AddTraineeCommand
        {
            get
            {
                return new RelayCommand(e => AddTrainee());
            }
        }

        public ICommand DeleteTraineeCommand
        {
            get
            {
                return new RelayCommand(e => DeleteTrainee(), e => TraineeList.Selected != null);
            }
        }

        [BusinessErrorDialog]
        private void AddTraineeGroup()
        {
            IAddTraineeGroupViewModel addTraineeGroupViewModel = DefaultServiceLocator.Get<IAddTraineeGroupViewModel>(); // TODO: use factory
            addTraineeGroupViewModel.OnCancel += () =>
            {
                ActiveTraineeGroup = null;
            };
            addTraineeGroupViewModel.OnAdd += (ITraineeGroup traineeGroup) =>
            {
                ActiveTraineeGroup = null;
                TraineeGroupList.RecreateItems();
            };

            ActiveTraineeGroup = addTraineeGroupViewModel;
        }

        [YesNoDialog("Warning: deleting this trainee group also removes it from any schedule it was linked with. The associated trainees will not be deleted. Do you really want to continue?")]
        [BusinessErrorDialog]
        private void DeleteTraineeGroup()
        {
            traineeGroupModel.Delete(TraineeGroupList.Selected.TraineeGroup);

            TraineeGroupList.RecreateItems();
        }

        [BusinessErrorDialog]
        private void AddTrainee()
        {
            IAddTraineeViewModel addTraineeViewModel = DefaultServiceLocator.Get<IAddTraineeViewModel>(); // TODO: use factory
            addTraineeViewModel.OnCancel += () =>
            {
                ActiveTrainee = null;
            };
            addTraineeViewModel.OnAdd += (ITrainee trainee) =>
            {
                ActiveTrainee = null;

                TraineeList.RecreateItems();
            };

            ActiveTrainee = addTraineeViewModel;
        }

        [YesNoDialog("Do you really want to delete this trainee?")]
        [BusinessErrorDialog]
        private void DeleteTrainee()
        {
            traineeModel.Delete(TraineeList.Selected.Trainee);

            TraineeList.RecreateItems();
        }

        private readonly ITraineeGroupModel traineeGroupModel;
        private readonly ITraineeModel traineeModel;

        private ITraineeGroupListViewModel traineeGroupList;
        private IViewModel activeTraineeGroup;

        private ITraineeListViewModel traineeList;
        private IViewModel activeTrainee;
    }
}
